﻿using Collector.Device;
using Collector.Device.Notify;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Collector.Factory
{
    public partial class FactoryForm : Form
    {
        private string TAG = "FactoryForm:";
        private FactorySettingForm mSettingFrom;
        private FactoryMain mFactoryMain = new FactoryMain();
        private ScanSn InputSn = null;
        private AutoResetEvent conditionWait = new AutoResetEvent(false);

        public SubItemView[] subItemView = new SubItemView[FileConfig.Max_Dut_Count];
        // 记录200个点用于计算平均压力值
        Queue<double> airPressure_data = new Queue<double>();
        Queue<double> wave_data = new Queue<double>();

        const int QUEUE_AIRPRESSURE_LENGTH = 10;
        const int THREE_BODY_PART_SNR_MAXIMUM = 3;
        double[] baseline_value = new double[THREE_BODY_PART_SNR_MAXIMUM];
        private string mFixedFrequency = null;
        private string mInputPCBSN = null;
        private bool mScanSnInputCancel = false;
        private bool mIsShuttingdown = false;

        public FactoryForm()
        {
            Log.Debug(TAG + "FactoryForm() Entry");
            InitializeComponent();
            this.Width = Screen.PrimaryScreen.Bounds.Width - 60;
            this.Height = Screen.PrimaryScreen.Bounds.Height - 60;
            this.splitContainer1.SplitterDistance = Screen.PrimaryScreen.Bounds.Width - 400;
            this.splitContainer3.SplitterDistance = Screen.PrimaryScreen.Bounds.Width - 640;

            this.toolStripButtonStopScope.Enabled = false;
            this.scopeDY.Visible = true;
            this.Shown += new System.EventHandler(this.FactoryForm_Shown);

            // 注册配置选项改变的通知事件
            AppEvent.RegistEvent(EventId.UpdateInfo, OnUpdateUI);
            AppEvent.RegistEvent(EventId.TestStop, OnTestStop);
            mSettingFrom = new FactorySettingForm();
            LogKeys.Init();

            Log.Debug(TAG + "FactoryForm() Leaved");
        }

        private void FactoryForm_Shown(object sender, EventArgs e)
        {
            Log.Debug(TAG + "FactoryForm_Shown() Entry");
            for (int i = 0; i < 1; i++)
            {
                subItemView[i] = new SubItemView(i);
                subItemView[i].SubItemIndex = i;
                subItemView[i].Dock = DockStyle.Fill;
                subItemView[i].Visible = true;
                panel3.Controls.Add(subItemView[i]);

            }
            this.Text = Application.ProductName + " - " + Application.ProductVersion;
            //this.label_TestMode.Text = FileConfig.testMode_Info[FileConfig.CommonParam.iSelectedTestmode].mode;

            Log.Debug(TAG + "FactoryForm_Shown() Leaved");
        }

        private void OnUpdateUI(object sender, AppEventArgs e)
        {
            if (e.State == EventState.UI)
            {
#if false
                //var info = e.Reserved;
                if (Convert.ToInt32(e.Reserved) == 0)
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_FACTORY;
                else if (Convert.ToInt32(e.Reserved) == 1)
                {
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_USER;
                }
                else if (Convert.ToInt32(e.Reserved) == 2)
                {
                    mCertifiedHandler.Mode = CertifiedMain.RunMode.eMODE_RUN_CERTIFIED;
                }
#endif
                //更新测试模式状态
                string TestModeInfo = e.Data as string;
                this.label_TestMode.Text = TestModeInfo;

                if (FileConfig.PulseThreeBodyTest())
                {
                    this.textBox_Pressure_Guan.Visible = true;
                    this.textBox_Pressure_Chi.Visible = true;
                    this.label_realtimePulsePressure1.Visible = true;
                    this.label_realtimePulsePressure2.Visible = true;
                    this.textBox_Baseline_Guan.Visible = true;
                    this.label1_baseline1.Visible = true;
                    this.textBox_Baseline_Chi.Visible = true;
                    this.label1_baseline2.Visible = true;
                    this.textBox_Diff_Guan.Visible = true;
                    this.label2_pulse_diff1.Visible = true;
                    this.textBox_Diff_Chi.Visible = true;
                    this.label2_pulse_diff2.Visible = true;
                }
                else
                {
                    this.textBox_Pressure_Guan.Visible = false;
                    this.textBox_Pressure_Chi.Visible = false;
                    this.label_realtimePulsePressure1.Visible = false;
                    this.label_realtimePulsePressure2.Visible = false;
                    this.textBox_Baseline_Guan.Visible = false;
                    this.label1_baseline1.Visible = false;
                    this.textBox_Baseline_Chi.Visible = false;
                    this.label1_baseline2.Visible = false;
                    this.textBox_Diff_Guan.Visible = false;
                    this.label2_pulse_diff1.Visible = false;
                    this.textBox_Diff_Chi.Visible = false;
                    this.label2_pulse_diff2.Visible = false;
                }
            }
        }

        private void OnTestStop(object sender, AppEventArgs e)
        {
            if (e.State != EventState.TestStop)
            {
                return;
            }

            this.Invoke(new MethodInvoker(delegate
            {
                // 模拟点击Stop Button按钮
                this.toolStripButtonStopScope.PerformClick();
            }));
        }

        private int DisplayMessageToUI(PulseCommonHelper.Display obj, PulseCommonHelper.Display.DisplayType type)
        {
            switch (type)
            {
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_MSG:
                    {
                        this.ShowMsg(obj.Message, obj.LogLevel);
                    }
                    break;
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_ITEM:
                    {

                    }
                    break;
                case PulseCommonHelper.Display.DisplayType.eDISPLAY_TYPE_USER:
                    {
                        if (this.msgComPort.InvokeRequired)
                        {
                            this.BeginInvoke(new Action(() =>
                            {
                                BackendProcessing((CollectorIntention)obj.UserData);
                            }
                            ));
                        }
                        else
                        {
                            BackendProcessing((CollectorIntention)obj.UserData);
                        }

                    }
                    break;
                default:
                    break;
            }

            return 0;
        }

        private bool BackendProcessing(CollectorIntention intent)
        {
            if (intent == null)
            {
                return false;
            }

            switch (intent.Type)
            {
                case CollectorIntention.IntentionType.eINTENT_TYPE_UPDATE_SERIALPORT_LABLE:
                    {
                        // 实时刷新测试时间
                        this.msgComPort.Invoke(new EventHandler(delegate
                        {
                            this.msgComPort.Text = intent.Message;
                        }));
                    }
                    break;
                case CollectorIntention.IntentionType.eINTENT_TYPE_REFRESH_TEST_TIME:
                    {
                        this.labTotalTime.Text = intent.Message;
                    }
                    break;
                case CollectorIntention.IntentionType.eINTENT_TYPE_UPDATE_SENSOR_DATA:
                    {
                        DeliveredPulsePressureDataCallback(intent);
                    }
                    break;
                case CollectorIntention.IntentionType.eINTENT_TYPE_UPDATE_GRAPH_CURVE:
                    {
                        getGraphCurveValue(intent);
                    }
                    break;
                case CollectorIntention.IntentionType.eINTENT_TYPE_UPDATE_DEVICE_VERSION:
                    {
                        // display version 
                        RunFuncWithShowItem(intent.Result, "Read MCUVersion", intent.Message + ", Read MCU Version Result");
                    }
                    break;
                case CollectorIntention.IntentionType.eINTENT_TYPE_UPDATE_BASELINE:
                    {
                        double[] baselines = (double[])intent.Data;
                        baselines.CopyTo(baseline_value, 0);
                        this.textBox_Baseline_Cun.Invoke(new EventHandler(delegate
                        {
                            this.textBox_Baseline_Cun.Text = baseline_value[0].ToString();
                            //this.textBox_Baseline_Cun.BackColor = Color.Green;
                            if (FileConfig.PulseThreeBodyTest())
                            {
                                this.textBox_Baseline_Guan.Text = baseline_value[1].ToString();
                                //this.textBox_Baseline_Guan.BackColor = Color.Green;
                                this.textBox_Baseline_Chi.Text = baseline_value[2].ToString();
                                //this.textBox_Baseline_Chi.BackColor = Color.Green;
                            }
                        }));
                    }
                    break;               
            }

            return true;
        }

        private bool DeliveredPulsePressureDataCallback(CollectorIntention intent)
        {
            PulseProtocolPackage.PressureType type = intent.PressureType;
            switch (type)
            {
                case PulseProtocolPackage.PressureType.ePRESSURE_TYPE_PULSE:
                    {
                        if (FileConfig.PulseThreeBodyTest())
                        {
                            foreach (var item in PulseApplicantion.TBPIndexMap)
                            {
                                double value = intent.AverageData[item.Key];

                                if (item.Value == BodyPart.eBODY_PART_CUN)
                                {
                                    scopeDY.Channels[0].Data.AddYPoint(value - baseline_value[0]);
                                }
                                else if (item.Value == BodyPart.eBODY_PART_GUAN)
                                {
                                    scopeDY.Channels[1].Data.AddYPoint(value - baseline_value[1]);
                                }
                                else if (item.Value == BodyPart.eBODY_PART_CHI)
                                {
                                    scopeDY.Channels[2].Data.AddYPoint(value - baseline_value[2]);
                                }
                            }
                        }
                        else
                        {
                            // Update scope plotlab value
                            //if (pluseDataMap.ContainsKey(BodyPart.eBODY_PART_CUN))
                            {
                                //double value = Math.Round(pluseDataMap[BodyPart.eBODY_PART_CUN].Last(), 2);
                                double value = intent.AverageData[0];
                                scopeDY.Channels[0].Data.AddYPoint(value - baseline_value[0]);
                            }
                        }
                    }
                    break;
                case PulseProtocolPackage.PressureType.ePRESSURE_TYPE_AIR:
                    {
                        double data = (double)intent.Data;
                        if (airPressure_data.Count >= QUEUE_AIRPRESSURE_LENGTH)
                            airPressure_data.Dequeue();//在队列的头部读取和删除一个元素，注意，这里读取元素的同时也删除了这个元素
                        airPressure_data.Enqueue(data);//在队列的末端添加元素

                    }
                    break;
            }

            return true;
        }

        private void getGraphCurveValue(CollectorIntention intent)
        {
            double airpresure_value = 0;
            double curveline_value = 0;
            double curDiffValue = 0;

            //BeginInvoke(new Action(() =>
            //{
            //testTmp++;
            if (FileConfig.PulseThreeBodyTest())
            {
                foreach (var item in PulseApplicantion.TBPIndexMap)
                {
                    if (item.Value == BodyPart.eBODY_PART_CUN)
                    {
                        //curveline_value = Math.Round(item.Value.Average(), 2);
                        curveline_value = intent.AverageData[item.Key];
                        curDiffValue = Math.Round((curveline_value - baseline_value[0]), 2);
                        //实时显示当前脉压值，1秒上报100次
                        this.textBox_Pressure_Cun.Text = curveline_value.ToString();
                        //实时显示脉压差值 单位: mbar
                        this.textBox_Diff_Cun.Text = curDiffValue.ToString();
                    }
                    else if (item.Value == BodyPart.eBODY_PART_GUAN)
                    {
                        //curveline_value = Math.Round(item.Value.Average(), 2);
                        curveline_value = intent.AverageData[item.Key];
                        curDiffValue = Math.Round((curveline_value - baseline_value[1]), 2);
                        //实时显示当前脉压值，1秒上报100次
                        this.textBox_Pressure_Guan.Text = curveline_value.ToString();
                        //实时显示脉压差值 单位: mbar
                        this.textBox_Diff_Guan.Text = curDiffValue.ToString();
                    }
                    else if (item.Value == BodyPart.eBODY_PART_CHI)
                    {
                        //curveline_value = Math.Round(item.Value.Average(), 2);
                        curveline_value = intent.AverageData[item.Key];
                        curDiffValue = Math.Round((curveline_value - baseline_value[2]), 2);
                        //实时显示当前脉压值，1秒上报100次
                        this.textBox_Pressure_Chi.Text = curveline_value.ToString();
                        //实时显示脉压差值 单位: mbar
                        this.textBox_Diff_Chi.Text = curDiffValue.ToString();

                    }
                }
            }
            else
            {
                //if (check && pulseDataMap.ContainsKey(BodyPart.eBODY_PART_CUN))
                if (true)
                {

                    curveline_value = (double)intent.AverageData[0];
                    curDiffValue = Math.Round((curveline_value - baseline_value[0]), 2);
                    //实时显示当前脉压值，1秒上报100次
                    this.textBox_Pressure_Cun.Text = curveline_value.ToString();
                    //实时显示脉压差值 单位: mbar
                    this.textBox_Diff_Cun.Text = curDiffValue.ToString();
                }
            }
            //Log.Debug(TAG + "curveline_value: {0}", curveline_value);
            if (airPressure_data.Count == QUEUE_AIRPRESSURE_LENGTH)
            {
                double[] pressure = airPressure_data.ToArray();
                double average = pressure.Average();
                airpresure_value = Math.Round(average, 2);

                this.textBox_AirPressure.Text = airpresure_value.ToString();//实时显示当前气压值，1秒上报10次

                //testTmp++;
                // airpresure_value = Math.Round(airpresure_value / 133.33, 2);
                //if (testTmp % 10 == 0)
                //    this.textBox_airPressure.Text = airpresure_value.ToString(); // Pa
            }
            //}));
        }

        private void CheckSelectOption()
        {
            if (FileConfig.PulseThreeBodyTest() && FileConfig.PulseSubsectionTest())
            {
                Log.Error(TAG + "三部和单部测试只能选择其一");
                throw new Exception(string.Format("三部和单部测试只能选择其一"));
            }

            if(FileConfig.AgingTest() && (FileConfig.LedTest() || FileConfig.WritePCBSN()))
            {
                Log.Error(TAG + "老化测试不能与LED测试和SN测试一起测试，只能单独测试");
                throw new Exception(string.Format("老化测试不能与LED测试和SN测试一起测试，只能单独测试"));
            }
        }

        void ScanSerialNumber_SerialNumberInputed(object sender, SerialNumberInputedEventArgs e)
        {
            // 获得写入的固定频率
            mFixedFrequency = e.ModuleIndex;//固定频率
            // 获得写入的SN号
            mInputPCBSN = e.SerialNumber;
            mScanSnInputCancel = e.Closed;
            this.ShowMsg("Get from barcode scanner :" + mInputPCBSN + " fix freq: " + mFixedFrequency, LogMsgType.INFO);
            conditionWait.Set();
        }

        private bool WriteDeviceSerialNumber()
        {
            this.Invoke((EventHandler)delegate
            {
                InputSn = new ScanSn();
                InputSn.SerialNumberInputed += new SerialNumberInputedEventHandler(ScanSerialNumber_SerialNumberInputed);
                InputSn.Show();
                InputSn.Focus();
                
            });

            // 等待用户输入SN号
            conditionWait.WaitOne();
            
            // 释放ScanSn
            if (InputSn != null)
            {
                InputSn.Close();
                InputSn.Dispose();
                InputSn = null;
            }

            if (mScanSnInputCancel)
            {
                Log.Error(TAG + "User donot input the new serialnumber.");
                return false;
            }

            string reason, serialnumber;
            bool ret = mFactoryMain.BurnDeviceSerialnumber(mInputPCBSN, out reason);
            if (!ret)
            {
                MessageBox.Show(reason, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                RunFuncWithShowItem(false, "Write new pcbSN", mInputPCBSN + ", Write Fail");
            } else
            {
                // 从设备读SN，进行校验
                ret = mFactoryMain.GetDeviceSerialnumber(out serialnumber);
                if(!ret)
                {
                    MessageBox.Show(reason, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RunFuncWithShowItem(false, "Read new pcbSN", mInputPCBSN + ", Read Fail");
                }
                else
                {
                    this.ShowMsg("Read SN From Dev:" + serialnumber, LogMsgType.INFO);
                    if (serialnumber != mInputPCBSN)
                    {
                        ret = false;
                        RunFuncWithShowItem(false, "Check new pcbSN", serialnumber + ", Check Fail");
                    } 
                    else
                    {
                        this.ShowMsg("Write And Read SN PASS", LogMsgType.DEBUG);
                        RunFuncWithShowItem(true, "Write pcbSN", mInputPCBSN + ", Write Success");
                    }
                }
            }

            return ret;
        }

        private bool WriteDeviceFixedFrequency()
        {
            if (!FileConfig.WritePCBSN()) {
                this.Invoke((EventHandler)delegate
                {
                    InputSn = new ScanSn();
                    InputSn.SerialNumberInputed += new SerialNumberInputedEventHandler(ScanSerialNumber_SerialNumberInputed);
                    InputSn.Show();
                    InputSn.Focus();

                });

                // 等待用户输入SN号
                conditionWait.WaitOne();

                // 释放ScanSn
                if (InputSn != null)
                {
                    InputSn.Close();
                    InputSn.Dispose();
                    InputSn = null;
                }

                if (mScanSnInputCancel)
                {
                    Log.Error(TAG + "User donot input the new serialnumber.");
                    return false;
                }
            }

            string frequency;
            bool ret = mFactoryMain.BurnDeviceFixedFrequency(mFixedFrequency);
            if (!ret)
            {
                RunFuncWithShowItem(false, "Write new pump frequency", mFixedFrequency + ", Write Fail");
            }
            else
            {
                // 从设备读气泵频率，进行校验
                ret = mFactoryMain.GetDeviceFixedFrequency(out frequency);
                if (!ret)
                {
                    RunFuncWithShowItem(false, "Read new pump frequency", mFixedFrequency + ", Read Fail");
                }
                else
                {
                    this.ShowMsg("Read pump frequency From Dev:" + frequency, LogMsgType.INFO);
                    if (frequency != mFixedFrequency)
                    {
                        ret = false;
                        RunFuncWithShowItem(false, "Check new pump frequency", frequency + ", Check Fail");
                    }
                    else
                    {
                        this.ShowMsg("Write And Read pump frequency PASS", LogMsgType.DEBUG);
                        RunFuncWithShowItem(true, "Write pump frequency", mFixedFrequency + ", Write Success");
                    }
                }
            }

            return ret;
        }

        private bool WriteDeviceAirSensorCalibration()
        {
            bool ret;
            double pressureOfPeeling;

            if (!mFactoryMain.BurnDeviceAirCalibration())
            {
                this.ShowMsg(string.Format("Air sensor Calibration ACK Answer Back Error."), LogMsgType.ERROR);
                RunFuncWithShowItem(false, "Write peel calibration" + ", Read Fail");
                return false;
            }

            // read pressureOfPeeling
            ret = mFactoryMain.GetAirpressureCalibration(out pressureOfPeeling);
            if (ret)
            {
                //下98指令,读取设备气压值3000Pa
                this.ShowMsg(string.Format("气压零飘值 :{0}Pa", pressureOfPeeling), LogMsgType.INFO);
                if (pressureOfPeeling >= FileConfig.GetThresholdValue("InitAirPressureValue"))
                {
                    Log.Debug("air pressure Calibration is not match, {0}Pa -> {1}Pa 气压传感器异常 ",
                        pressureOfPeeling, FileConfig.GetThresholdValue("InitAirPressureValue"));

                    RunFuncWithShowItem(false, "Check Calibration:", pressureOfPeeling + ", Check Fail");
                    throw new Exception(string.Format("{0}Pa -> {1}Pa 气压传感器异常",
                        pressureOfPeeling, FileConfig.GetThresholdValue("InitAirPressureValue")));                    
                } 
                else
                {
                    RunFuncWithShowItem(true, "Write Peel Calibration", "remove peel: " + pressureOfPeeling + ", Write Success");
                }
            }
            else
            {
                Log.Debug("Read air pressure of the peel is failed");
                RunFuncWithShowItem(false, "Read Calibration:", "peel: " + pressureOfPeeling + ", Read Fail");
            }

            return ret;
        }

        private bool LedDeviceTest()
        {
            bool ret = false;
            this.Invoke(new EventHandler(delegate
            {
                LedFrm ledFrm = new LedFrm(mFactoryMain.SerialPort.SerialPort, TestItemFlow.Led1Test);
                ledFrm.ShowDialog();
                ret = ledFrm.TestState;
                RunFuncWithShowItem(ret, "LED 灯测试", "LED 灯测试结果");
                if (ret)
                {
                    this.ShowMsg("LED test PASS", LogMsgType.DEBUG);
                }
                else
                {
                    this.ShowMsg("LED test FAIL", LogMsgType.ERROR);
                }
            }));

            return ret;
        }
        private bool KeepRunning()
        {
            bool ret = false;
            int i;
            // Get loop count
            int loopCount = FileConfig.GetConfigValueToInt("AgingCount");            
            Log.Debug(TAG + "CycleCount: " + loopCount);
            for(i=0; i<loopCount && !mIsShuttingdown; i++)
            {
                this.ShowMsg(string.Format("开始第{0}次循环...", i+1), LogMsgType.DEBUG);
                ret = PulseSegmented();

                if (i < loopCount - 1)
                {
                    this.ShowMsg(string.Format("结束第{0}次循环,等待下次循环.", i + 1), LogMsgType.DEBUG);
                    Thread.Sleep(15 * 1000);
                }
                else
                {
                    this.ShowMsg(string.Format("结束第{0}次循环, 循环测试完成.", i + 1), LogMsgType.DEBUG);
                }
            }

            return true;
        }

        private bool PulseSegmentedCheck()
        {
            bool ret = false;
            ret = mFactoryMain.Check();
            if (ret)
            {
                ProFrm Frm_ = new ProFrm(string.Format("请正确佩戴设备,状态指示灯正常!."));
                Frm_.ShowDialog(this);
                if (!Frm_.TestState)
                {
                    this.ShowMsg(TAG + string.Format("未正确佩戴设备，测试结束"), LogMsgType.ERROR);
                    ret = false;
                }
            }

            return ret;
        }

        private bool PulseSegmented()
        {
            return mFactoryMain.Start();
        }

        private void StartFactoryWork()
        {
            Thread nth = new Thread(() =>
            {
                bool ret = false;
                // UI 初始化清空
                this.Invoke((EventHandler)delegate
                {
                    this.toolStripButtonRunScope.Enabled = false;
                    this.toolStripButtonStopScope.Enabled = true;
                    this.scopeDY.Visible = true;

                    //清除listView数据
                    AppEvent.CallEvent(this, new AppEventArgs(EventId.TestStart, 0, EventState.Invalid, null, null));
                    // 清空右侧显示测试结果的文本框
                    this.rtbMsg.Clear();

                    this.scopeDY.Channels[0].Data.Clear();
                    this.scopeDY.Channels[1].Data.Clear();
                    this.scopeDY.Channels[2].Data.Clear();
                    if (this.scopeDY.SizeLimit != 300)
                    {
                        this.scopeDY.SizeLimit = 300;
                        this.scopeDY.RefreshInterval = 100;
                        this.scopeDY.RefreshView();
                    }
                });

                this.ShowInfo("Running", Color.Yellow);
                mIsShuttingdown = false;

                //变量重新初始化
                for (int i = 0; i < THREE_BODY_PART_SNR_MAXIMUM; i++)
                    baseline_value[i] = 0;

                this.wave_data.Clear();
                this.airPressure_data.Clear();

                /**
                 * 初始化设备
                 */
                string mmHgInfo;
                double bmmHgThreSValue = FileConfig.GetThresholdValue("mmHgThresholdValue");
                // 从配置文件中读取分段压力值
                if (!FileConfig.getmmHgListInfo("mmHg_pPressureList", out mmHgInfo))
                {
                    this.ShowMsg(string.Format("{0} 脉压集合列表初始化失败", mmHgInfo), LogMsgType.ERROR);
                    return;
                }

                mFactoryMain.notifyForm += new FormNotifyDelegate<PulseCommonHelper.Display>(DisplayMessageToUI);
                ret = mFactoryMain.Prepared(bmmHgThreSValue, mmHgInfo,
                        FileConfig.PulseThreeBodyTest() ? ProductType.ePRODUCT_TYPE_THREE : ProductType.ePRODUCT_TYPE_SINGLE, false);

                if(!ret)
                {
                    Log.Error(TAG + "FactoryMain preparing failed");
                    return;
                }

                // 功能检测
                do
                {
                    // 写SN
                    if (FileConfig.WritePCBSN())
                    {
                        ret = WriteDeviceSerialNumber();
                        if (!ret)
                        {
                            break;
                        }
                    }

                    // 写气泵固定频率
                    if(FileConfig.WriteFixedFrequency())
                    {
                        ret = WriteDeviceFixedFrequency();
                        if(!ret)
                        {
                            break;
                        }
                    }

                    if(FileConfig.AirResetTest())
                    {
                        ret = WriteDeviceAirSensorCalibration();
                        if (!ret)
                        {
                            break;
                        }
                    }

                    // 测试LED
                    if (FileConfig.LedTest())
                    {
                        ret = LedDeviceTest();
                        if (!ret) break;
                    }

                    // 老化测试
                    if (FileConfig.AgingTest())
                    {
                        ret = PulseSegmentedCheck();
                        if (!ret) break;

                        ret = KeepRunning();
                        if (!ret) break;
                    } 
                    else if(FileConfig.PulseFFTTest() || FileConfig.PulseSFTTest())
                    {
                        // 正常功能检测
                        ret = PulseSegmentedCheck();
                        if (!ret) break;

                        ret = PulseSegmented();
                    }

                } while (false);

                if(ret)
                {
                    this.ShowInfo("PASS", Color.Green);
                }
                else
                {
                    this.ShowInfo("FAIL", Color.Red);
                }

                // 回收资源
                mFactoryMain.Stop();
                mFactoryMain.notifyForm -= new FormNotifyDelegate<PulseCommonHelper.Display>(DisplayMessageToUI);

            });

            nth.Start();
            
        }

        private void btn_StopReset_Click(object sender, EventArgs e)
        {

        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.ShowMsg("MainForm_FormClosing Click", LogMsgType.INFO);
            if (MessageBox.Show("Exit?", Application.ProductName, MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    toolStripButtonStopScope_Click(null, null);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(string.Format("Close MainForm...Delete packet And Kill Process Fail...{0}", ex.Message));
                }
                Dispose();
            }
            else
            {
                e.Cancel = true;
            }
        }

        private void btn_ManualTest_Click(object sender, EventArgs e)
        {

        }

        private void btn_ManualPress_Click(object sender, EventArgs e)
        {

        }

        private void btn_RefeshBaseLine_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButtonExit_Click(object sender, EventArgs e)
        {
            this.ShowMsg("Exit_Click", LogMsgType.INFO);
            this.Close();
        }

        private void tsBtn_version_Click(object sender, EventArgs e)
        {
            MessageBox.Show(Application.ProductName + "-" + Application.ProductVersion, "版本信息", MessageBoxButtons.OK);
        }

        private void toolStripButtonOpenLog_Click(object sender, EventArgs e)
        {
            //Process.Start("explorer.exe", Application.StartupPath + "\\logs");
        }

        private void toolStripButtonAnalyse_Click(object sender, EventArgs e)
        {

        }
        private void toolStripButtonReplay_Click_1(object sender, EventArgs e)
        {

        }

        private void toolStripButtonSave_Click(object sender, EventArgs e)
        {
            //MatlabSaveToBitmap();
            MessageBox.Show("波形保存成功");
            return;
        }

        private void Stop()
        {
            mIsShuttingdown = true;
            mFactoryMain.Stop(new Action(() => {
                this.Invoke((EventHandler)delegate
                {
                    this.toolStripButtonRunScope.Enabled = true;
                });
            }));
            mFactoryMain.notifyForm -= new FormNotifyDelegate<PulseCommonHelper.Display>(DisplayMessageToUI);

        }

        private async void toolStripButtonStopScope_Click(object sender, EventArgs e)
        {
            this.ShowMsg("StopScope_Click", LogMsgType.INFO);
            this.toolStripButtonStopScope.Enabled = false;

            try
            {
                await Task.Run(new Action(Stop));
            }
            finally
            {
                this.ShowMsg("finaly StopScope_Click", LogMsgType.INFO);
            }
        }
            /// 开始测试按钮，点击后开始脉象功能测试
        private void toolStripButtonRunScope_Click(object sender, EventArgs e)
        {
            Log.Debug(TAG + "toolStripButtonRunScope_Click() Entry");

            try
            {
                CheckSelectOption();
            }
            catch (Exception ex)
            {
                this.ShowInfo("FAIL", Color.Red);
                this.ShowMsg("CaughtException :" + ex.Message, LogMsgType.ERROR);
                return;
            }

            StartFactoryWork();

            Log.Debug("toolStripButtonRunScope_Click() Leaved");
        }

        private void toolStripButtonConfig_Click(object sender, EventArgs e)
        {
            mSettingFrom.ShowDialog();
        }

        private void ShowInfo(string info, Color clr)
        {
            this.lbEndMsg.Invoke(new EventHandler(delegate
            {
                this.lbEndMsg.ForeColor = clr;
                this.lbEndMsg.Text = info;
            }));
        }

        private void ShowMsg(string msg, LogMsgType msgType)
        {
            Color _color = (msgType == LogMsgType.ERROR ? Color.Red : msgType == LogMsgType.DEBUG ? Color.Blue : Color.Black);
            if (msgType != LogMsgType.MSG)
                Log.Debug(msg);
            if (rtbMsg.InvokeRequired)
            {
                Action<string> act = (obj) =>
                {
                    rtbMsg.SelectionColor = _color;
                    rtbMsg.AppendText(obj + "\r\n");
                    rtbMsg.ScrollToCaret();
                };
                rtbMsg.Invoke(act, msg);
            }
            else
            {
                rtbMsg.SelectionColor = _color;
                rtbMsg.AppendText(msg + "\r\n");
                rtbMsg.ScrollToCaret();
            }
        }

        private bool RunFuncWithShowItem(bool FuncResult, string itemName, string Iteminfo = "")
        {
            bool bok = FuncResult;
            ShowItem(itemName, Iteminfo, 1, bok ? 1 : 0, 1);

            return bok;
        }
        private void ShowItem(string ItemName, string ItemInfo, double dlow, double value, double dhigh, string unit = "")
        {
            UIItemInfo info = new UIItemInfo();
            info.ItemName = ItemName.Trim();
            info.info = ItemInfo.Trim();
            //info.LimitLow = dlow.ToString();
            info.TestValue = value.ToString();
            //info.LimitHigh = dhigh.ToString();
            //info.TestUnit = unit;
            info.ItemResult = (dlow <= value && value <= dhigh) ? "PASS" : "FAIL";

            AppEvent.CallEvent(this, new AppEventArgs(EventId.AddLog, 999, EventState.LOG_ITEM, info, null));
        }
    }
}
